#ifndef __MODEL_OBJ_H__
#define __MODEL_OBJ_H__

#include "../3ds/io/io3ds.h"
#include "../3ds/model.h"
#include "../3ds/material.h"
#include "render/rendermgr.h"
#include "../renderobj.h"

#define MODEL_DEFINE \
public:\
	static const string GetObjName();\
private:\
	static const string s_strObjName;\

#define DEF_MODEL_NAME(classname,name) \
	const string classname::s_strObjName = name;\
	const string classname::GetObjName()\
	{\
		return s_strObjName;\
	}\
	Lib3dsFile* ModelObj<classname>::s_pFile = NULL;\
	Model ModelObj<classname>::s_model;\
	Material ModelObj<classname>::s_material;

template <class T>
class ModelObj : public RenderObj
{
public:
	ModelObj()
	{
		if (!s_pFile)
		{
			s_pFile = IO3ds::GetInstance().FileOpen(T::GetObjName() + ".3ds");
			s_model.LoadBy3dsFile(s_pFile);
			s_material.LoadBy3dsFile(s_pFile);
		}

		m_model.LoadByModel(s_model);
		m_material.LoadByMaterial(s_material);

		RenderMgr::GetInstance().OnRender += EventObject<OnRenderFunc>(this, &ModelObj<T>::OnRender);
		m_model.OnRenderMaterial += EventObject<OnRenderMaterialFunc>(this, &ModelObj<T>::OnRenderMaterial);
	}

	virtual ~ModelObj()
	{
		m_model.OnRenderMaterial -= EventObject<OnRenderMaterialFunc>(this, &ModelObj<T>::OnRenderMaterial);
		RenderMgr::GetInstance().OnRender -= EventObject<OnRenderFunc>(this, &ModelObj<T>::OnRender);
	}

protected:
	virtual void OnRenderMaterial(int texid)
	{
		m_material.Render(texid);
	}

	virtual void OnRender(float differTime)
	{
		if (m_bVisible)
		{
			m_model.Render();
		}
	}

protected:
	Model m_model;
	Material m_material;

protected:
	static Lib3dsFile* s_pFile;
	static Model s_model;
	static Material s_material;
};

#endif